package service

import (
	"context"

	"encoding/json"
	"fmt"
	"github.com/LyricTian/gin-admin/v8/pkg/util/yaml"
	"os"

	"github.com/google/wire"

	"github.com/LyricTian/gin-admin/v8/internal/app/dao"
	"github.com/LyricTian/gin-admin/v8/internal/app/schema"
	"github.com/LyricTian/gin-admin/v8/pkg/errors"
	"github.com/LyricTian/gin-admin/v8/pkg/util/snowflake"
)

var DemoSet = wire.NewSet(wire.Struct(new(DemoSrv), "*"))

type DemoSrv struct {
	TransRepo *dao.TransRepo
	DemoRepo  *dao.DemoRepo
}

type DemoSchema []*schema.Demo

// InitData 初始化菜单数据
func (a *DemoSrv) InitData(ctx context.Context, dataFile string) error {
	fmt.Println(dataFile)

	result, err := a.DemoRepo.Query(ctx, schema.DemoQueryParam{
		PaginationParam: schema.PaginationParam{OnlyCount: true},
	})
	if err != nil {
		return err
	} else if result.PageResult.Total > 0 {
		// 如果存在则不进行初始化
		return nil
	}
	// var data DemoSchema
	data, err := a.readData(dataFile)

	// res, _ := json.Marshal(data)
	// fmt.Printf("%s", res)

	if err != nil {
		return err
	}
	return a.createDemos(ctx, data)

}

func (a *DemoSrv) readData(name string) (DemoSchema, error) {
	var data DemoSchema
	file, err := os.Open(name)
	if err != nil {
		return data, err
	}
	defer file.Close()
	// d := util.YAMLNewDecoder(file)
	d := yaml.NewDecoder(file)
	d.SetStrict(true)
	err = d.Decode(&data)
	return data, err
}

func (a *DemoSrv) createDemos(ctx context.Context, list DemoSchema) error {

	err := a.TransRepo.Exec(ctx, func(ctx context.Context) error {
		for _, item := range list {
			sitem := schema.Demo{
				Code: item.Code,
				Name: item.Name,
				Memo: item.Memo,
			}
			fmt.Println("1111")

			_, err := a.Create(ctx, sitem)
			if err != nil {
				fmt.Println(err)

				return err
			}
			res, _ := json.Marshal(sitem)
			fmt.Printf("%s", res)

		}

		res, _ := json.Marshal(list)
		fmt.Printf("%s", res)

		return nil

	})
	if err != nil {
		return nil
	}
	// return schema.NewIDResult(item.ID), nil
	return nil
}

func (a *DemoSrv) Query(ctx context.Context, params schema.DemoQueryParam, opts ...schema.DemoQueryOptions) (*schema.DemoQueryResult, error) {
	result, err := a.DemoRepo.Query(ctx, params, opts...)
	if err != nil {
		return nil, err
	}
	return result, nil
}

func (a *DemoSrv) Get(ctx context.Context, id uint64, opts ...schema.DemoQueryOptions) (*schema.Demo, error) {
	item, err := a.DemoRepo.Get(ctx, id, opts...)
	if err != nil {
		return nil, err
	} else if item == nil {
		return nil, errors.ErrNotFound
	}

	return item, nil
}

func (a *DemoSrv) Create(ctx context.Context, item schema.Demo) (*schema.IDResult, error) {
	item.ID = snowflake.MustID()

	err := a.TransRepo.Exec(ctx, func(ctx context.Context) error {
		return a.DemoRepo.Create(ctx, item)
	})
	if err != nil {
		return nil, err
	}

	return schema.NewIDResult(item.ID), nil
}

func (a *DemoSrv) Update(ctx context.Context, id uint64, item schema.Demo) error {
	oldItem, err := a.Get(ctx, id)
	if err != nil {
		return err
	} else if oldItem == nil {
		return errors.ErrNotFound
	}

	item.ID = oldItem.ID
	item.Creator = oldItem.Creator
	item.CreatedAt = oldItem.CreatedAt

	return a.TransRepo.Exec(ctx, func(ctx context.Context) error {
		return a.DemoRepo.Update(ctx, id, item)
	})
}

func (a *DemoSrv) Delete(ctx context.Context, id uint64) error {
	oldItem, err := a.DemoRepo.Get(ctx, id)
	if err != nil {
		return err
	} else if oldItem == nil {
		return errors.ErrNotFound
	}

	return a.TransRepo.Exec(ctx, func(ctx context.Context) error {
		return a.DemoRepo.Delete(ctx, id)
	})
}

func (a *DemoSrv) UpdateStatus(ctx context.Context, id uint64, status int) error {
	oldItem, err := a.DemoRepo.Get(ctx, id)
	if err != nil {
		return err
	} else if oldItem == nil {
		return errors.ErrNotFound
	} else if oldItem.Status == status {
		return nil
	}

	return a.DemoRepo.UpdateStatus(ctx, id, status)
}
